package com.hope.reflection.question;

import com.hope.Cat;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * 反射问题到引入
 */
public class ReflectionQuestion {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        //根据配置文件 re.properties 指定信息，创建Cat对象并调用方法hi

//        传统的方法 new 对象 --> 调用方法
//        Cat cat=new Cat();
//        cat.hi();---> cat.cry(); 传统方法要修改源码


        //1. 使用 Properties类，可以读取配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("reflection/src/main/resources/re.properties"));
        String classfullpath = properties.get("classfullpath").toString();
        String methodName = properties.get("method").toString();

        System.out.println("classfullpath=" + classfullpath);
        System.out.println("methodName=" + methodName);

        //2. 创建对象 ，传统方法行不通，=》 反射机制
        //new classfullpath 因为通过Properties类读取配置文件 得到的classfullpath 是String

        //3. 使用反射机制解决
        //（1）加载类 返回Class类型的对象
        Class cls = Class.forName(classfullpath);
        //（2）通过 cls 得到你加载的类的 com.hope.cat 对象的实例
        Object o = cls.getDeclaredConstructor().newInstance();
//        getClass(）返回Class类型的对象
        System.out.println("o的运行类型=" + o.getClass());//打印运行类型
        // (3) 通过clas得到你加载的类 com.hope.Cat的methodName"hi"的方法对象
        // 即：在反射中，可以把方法视为 对象 （万物皆对象）
        Method method1 = cls.getMethod(methodName);
        //（4）通过method1 调用方法：通过方法对象对象来实现调用方法
        method1.invoke(o);
    }

}
